blob: 58cad8ae1c3ffe961056e6cfbe0563d0bcf6fe0d [file] [log] [blame]
Soares Chen172fe9d2017-07-18 09:30:181<!doctype html>
2<meta charset=utf-8>
3<title>RTCRtpParameters codecs</title>
4<script src="/resources/testharness.js"></script>
5<script src="/resources/testharnessreport.js"></script>
6<script src="dictionary-helper.js"></script>
7<script src="RTCRtpParameters-helper.js"></script>
8<script>
9 'use strict';
10
11 // Test is based on the following editor draft:
12 // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
13
14 // The following helper functions are called from RTCRtpParameters-helper.js:
15 // validateSenderRtpParameters
16
17 /*
18 5.2. RTCRtpSender Interface
19 interface RTCRtpSender {
20 Promise<void> setParameters(optional RTCRtpParameters parameters);
21 RTCRtpParameters getParameters();
22 };
23
24 dictionary RTCRtpParameters {
25 DOMString transactionId;
26 sequence<RTCRtpEncodingParameters> encodings;
27 sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
28 RTCRtcpParameters rtcp;
29 sequence<RTCRtpCodecParameters> codecs;
30 RTCDegradationPreference degradationPreference;
31 };
32
33 dictionary RTCRtpCodecParameters {
34 [readonly]
35 unsigned short payloadType;
36
37 [readonly]
38 DOMString mimeType;
39
40 [readonly]
41 unsigned long clockRate;
42
43 [readonly]
44 unsigned short channels;
45
46 [readonly]
47 DOMString sdpFmtpLine;
48 };
49
50 getParameters
51 - The codecs sequence is populated based on the codecs that have been negotiated
52 for sending, and which the user agent is currently capable of sending.
53
54 If setParameters has removed or reordered codecs, getParameters MUST return
55 the shortened/reordered list. However, every time codecs are renegotiated by
56 a new offer/answer exchange, the list of codecs MUST be restored to the full
57 negotiated set, in the priority order indicated by the remote description,
58 in effect discarding the effects of setParameters.
59
60 codecs
61 - When using the setParameters method, the codecs sequence from the corresponding
62 call to getParameters can be reordered and entries can be removed, but entries
63 cannot be added, and the RTCRtpCodecParameters dictionary members cannot be modified.
64 */
65
66 // Get the first codec from param.codecs.
67 // Assert that param.codecs has at least one element
68 function getFirstCodec(param) {
69 const { codecs } = param;
70 assert_greater_than(codecs.length, 0);
71 return codecs[0];
72 }
73
74 /*
75 5.2. setParameters
76 7. If parameters.encodings.length is different from N, or if any parameter
77 in the parameters argument, marked as a Read-only parameter, has a value
78 that is different from the corresponding parameter value returned from
79 sender.getParameters(), abort these steps and return a promise rejected
80 with a newly created InvalidModificationError. Note that this also applies
81 to transactionId.
82 */
83 promise_test(t => {
84 const pc = new RTCPeerConnection();
85 const { sender } = pc.addTransceiver('audio');
86 const param = sender.getParameters();
87 validateSenderRtpParameters(param);
88
89 const codec = getFirstCodec(param);
90
91 if(codec.payloadType === undefined) {
92 codec.payloadType = 8;
93 } else {
94 codec.payloadType += 1;
95 }
96
97 return promise_rejects(t, 'InvalidModificationError',
98 sender.setParameters(param));
99
100 }, 'setParameters() with codec.payloadType modified should reject with InvalidModificationError');
101
102 promise_test(t => {
103 const pc = new RTCPeerConnection();
104 const { sender } = pc.addTransceiver('audio');
105 const param = sender.getParameters();
106 validateSenderRtpParameters(param);
107
108 const codec = getFirstCodec(param);
109
110 if(codec.mimeType === undefined) {
111 codec.mimeType = 'audio/piedpiper';
112 } else {
113 codec.mimeType = `${codec.mimeType}-modified`;
114 }
115
116 return promise_rejects(t, 'InvalidModificationError',
117 sender.setParameters(param));
118
119 }, 'setParameters() with codec.mimeType modified should reject with InvalidModificationError');
120
121 promise_test(t => {
122 const pc = new RTCPeerConnection();
123 const { sender } = pc.addTransceiver('audio');
124 const param = sender.getParameters();
125 validateSenderRtpParameters(param);
126
127 const codec = getFirstCodec(param);
128
129 if(codec.clockRate === undefined) {
130 codec.clockRate = 8000;
131 } else {
132 codec.clockRate += 1;
133 }
134
135 return promise_rejects(t, 'InvalidModificationError',
136 sender.setParameters(param));
137
138 }, 'setParameters() with codec.clockRate modified should reject with InvalidModificationError');
139
140 promise_test(t => {
141 const pc = new RTCPeerConnection();
142 const { sender } = pc.addTransceiver('audio');
143 const param = sender.getParameters();
144 validateSenderRtpParameters(param);
145
146 const codec = getFirstCodec(param);
147
148 if(codec.channels === undefined) {
149 codec.channels = 6;
150 } else {
151 codec.channels += 1;
152 }
153
154 return promise_rejects(t, 'InvalidModificationError',
155 sender.setParameters(param));
156
157 }, 'setParameters() with codec.channels modified should reject with InvalidModificationError');
158
159
160 promise_test(t => {
161 const pc = new RTCPeerConnection();
162 const { sender } = pc.addTransceiver('audio');
163 const param = sender.getParameters();
164 validateSenderRtpParameters(param);
165
166 const codec = getFirstCodec(param);
167
168 if(codec.sdpFmtpLine === undefined) {
169 codec.sdpFmtpLine = 'a=fmtp:98 0-15';
170 } else {
171 codec.sdpFmtpLine = `${codec.sdpFmtpLine};foo=1`;
172 }
173
174 return promise_rejects(t, 'InvalidModificationError',
175 sender.setParameters(param));
176
177 }, 'setParameters() with codec.sdpFmtpLine modified should reject with InvalidModificationError');
178
179
180 promise_test(t => {
181 const pc = new RTCPeerConnection();
182 const { sender } = pc.addTransceiver('audio');
183 const param = sender.getParameters();
184 validateSenderRtpParameters(param);
185
186 const { codecs } = param;
187
188 codecs.push({
189 payloadType: 2,
190 mimeType: 'audio/piedpiper',
191 clockRate: 1000,
192 channels: 2
193 });
194
195 return promise_rejects(t, 'InvalidModificationError',
196 sender.setParameters(param));
197
198 }, 'setParameters() with new codecs inserted should reject with InvalidModificationError');
199
200 promise_test(t => {
201 const pc = new RTCPeerConnection();
202 const { sender } = pc.addTransceiver('audio');
203 const param = sender.getParameters();
204 validateSenderRtpParameters(param);
205
206 const { codecs } = param;
207
208 // skip and pass test if there is less than 2 codecs
209 if(codecs.length >= 2) {
210 const tmp = codecs[0];
211 codecs[0] = codecs[1];
212 codecs[1] = tmp;
213 }
214
215 return sender.setParameters(param);
216
217 }, 'setParameters with reordered codecs should succeed');
218
219 promise_test(t => {
220 const pc = new RTCPeerConnection();
221 const { sender } = pc.addTransceiver('audio');
222 const param = sender.getParameters();
223 validateSenderRtpParameters(param);
224
225 const { codecs } = param;
226
227 param.codecs = codecs.slice(1);
228
229 return sender.setParameters(param);
230
231 }, 'setParameters with dropped codec should succeed');
232
233</script>